/**
 *=============================================================================
 *  @copyright (C)      2025CCUT_1024lab_Damocles
 *
 *  @file    drv_can.c
 *  @brief   仿照USTC-RoboWalker改写的CAN通信初始化与配置流程
 *
 *  @note    使用方法
 *
 *  @attention 注意事项
 *-----------------------------------------------------------------------------
 *  @version    @author    @date    @note
 *  V1.0.0      yssickjgd  220802   done
 *  V1.0.0      cherno     250808   done
 *==============================================================================
 */

/*==============================Includes======================================*/
#include "drv_can.h"
/*==============================PrivateMacros=================================*/

/*==============================PrivateTypes==================================*/

/*==============================PrivateVariables==============================*/
can_manager_t can1_manager = {0};
can_manager_t can2_manager = {0};

uint8_t can1_0x1fe_tx_data[8];
uint8_t can1_0x1ff_tx_data[8];
uint8_t can1_0x200_tx_data[8];
uint8_t can1_0x2fe_tx_data[8];
uint8_t can1_0x2ff_tx_data[8];
uint8_t can1_0x3fe_tx_data[8];
uint8_t can1_0x4fe_tx_data[8];

uint8_t can2_0x1fe_tx_data[8];
uint8_t can2_0x1ff_tx_data[8];
uint8_t can2_0x200_tx_data[8];
uint8_t can2_0x2fe_tx_data[8];
uint8_t can2_0x2ff_tx_data[8];
uint8_t can2_0x3fe_tx_data[8];
uint8_t can2_0x4fe_tx_data[8];

/*==============================PrivateFunctionDeclarations===================*/

/*==============================FunctionPrototypes============================*/

/**
 * @brief 配置CAN的过滤器
 *
 * @param hcan CAN编号
 * @param Object_Para 编号 | FIFOx | ID类型 | 帧类型
 * @param ID ID
 * @param Mask_ID 屏蔽位(0x3ff, 0x1fffffff)
 * @note 配置一个过滤器：使用过滤器编号5，存入FIFO1，用于扩展帧和数据帧
 * object_para = CAN_FILTER(5) | CAN_FIFO_1 | CAN_EXTID | CAN_DATA_TYPE;
 */
static void can_filter_mask_config(CAN_HandleTypeDef* hcan, uint8_t object_para,
                            uint32_t ID, uint32_t MaskId)
{
	CAN_FilterTypeDef can_filter_init_structure;

	// 检测传参是否正确
	assert_param(hcan != NULL);

	// 数据帧
	if ((object_para & 0x02)) {
		/* 掩码后ID的高16bit */
		can_filter_init_structure.FilterIdHigh = ID << 3 << 16;
		/* 掩码后ID的低16bit */
		can_filter_init_structure.FilterIdLow =
		    ID << 3 | ((object_para & 0x03) << 1);
		/* ID掩码值高16bit */
		can_filter_init_structure.FilterMaskIdHigh = MaskId << 3 << 16;
		/* ID掩码值低16bit */
		can_filter_init_structure.FilterMaskIdLow =
		    MaskId << 3 | ((object_para & 0x03) << 1);
	}
	// 其他帧
	else {
		/* 掩码后ID的高16bit */
		can_filter_init_structure.FilterIdHigh = ID << 5;
		/* 掩码后ID的低16bit */
		can_filter_init_structure.FilterIdLow = ((object_para & 0x03) << 1);
		/* ID掩码值高16bit */
		can_filter_init_structure.FilterMaskIdHigh = MaskId << 5;
		/* ID掩码值低16bit */
		can_filter_init_structure.FilterMaskIdLow = ((object_para & 0x03) << 1);
	}
	/* 滤波器序号, 0-27, 共28个滤波器, 前14个在CAN1, 后14个在CAN2 */
	can_filter_init_structure.FilterBank = object_para >> 3;
	/* 滤波器绑定FIFO 0 */
	can_filter_init_structure.FilterFIFOAssignment = (object_para >> 2) & 0x01;
	/* 使能滤波器 */
	can_filter_init_structure.FilterActivation = ENABLE;
	/* 滤波器模式，设置ID掩码模式 */
	can_filter_init_structure.FilterMode = CAN_FILTERMODE_IDMASK;
	/* 32位滤波 */
	can_filter_init_structure.FilterScale = CAN_FILTERSCALE_32BIT;
	can_filter_init_structure.SlaveStartFilterBank = 14;
	// 从机模式选择开始单元
	HAL_CAN_ConfigFilter(hcan, &can_filter_init_structure);
}

/**
 * @brief 初始化CAN总线
 *
 * @param hcan CAN编号
 * @param call_back_function 处理回调函数
 */
// static void can_filter_init(void)
// {
// 	CAN_FilterTypeDef can_filter_st;
// 	can_filter_st.FilterActivation = ENABLE;
// 	can_filter_st.FilterMode = CAN_FILTERMODE_IDMASK;
// 	can_filter_st.FilterScale = CAN_FILTERSCALE_32BIT;
// 	can_filter_st.FilterIdHigh = 0x0000;
// 	can_filter_st.FilterIdLow = 0x0000;
// 	can_filter_st.FilterMaskIdHigh = 0x0000;
// 	can_filter_st.FilterMaskIdLow = 0x0000;
// 	can_filter_st.FilterBank = 0;
// 	can_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0;
// 	HAL_CAN_ConfigFilter(&hcan1, &can_filter_st);
// 	HAL_CAN_Start(&hcan1);
// 	HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);

// 	can_filter_st.SlaveStartFilterBank = 14;
// 	can_filter_st.FilterBank = 14;
// 	HAL_CAN_ConfigFilter(&hcan2, &can_filter_st);
// 	HAL_CAN_Start(&hcan2);
// 	HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
// }
// void can_init(CAN_HandleTypeDef* hcan, can_call_back callback_function)
// {
// 	can_filter_init();
// 	if (hcan->Instance == CAN1) {
// 		can1_manager.hcan = hcan;
// 		can1_manager.call_back_function = callback_function;
// 	} else if (hcan->Instance == CAN2) {
// 		can2_manager.hcan = hcan;
// 		can2_manager.call_back_function = callback_function;
// 	}
// }

void can_init(CAN_HandleTypeDef* hcan, can_call_back call_back_function)
{
	if (hcan->Instance == CAN1) {
		can1_manager.hcan = hcan;
		can1_manager.call_back_function = call_back_function;
		can_filter_mask_config(
		    hcan, CAN_FILTER(0) | CAN_FIFO_0 | CAN_STDID | CAN_DATA_TYPE, 0, 0);
		can_filter_mask_config(
		    hcan, CAN_FILTER(1) | CAN_FIFO_1 | CAN_STDID | CAN_DATA_TYPE, 0, 0);
	} else if (hcan->Instance == CAN2) {
		can2_manager.hcan = hcan;
		can2_manager.call_back_function = call_back_function;
		can_filter_mask_config(
		    hcan, CAN_FILTER(14) | CAN_FIFO_0 | CAN_STDID | CAN_DATA_TYPE, 0,
		    0);
		can_filter_mask_config(
		    hcan, CAN_FILTER(15) | CAN_FIFO_1 | CAN_STDID | CAN_DATA_TYPE, 0,
		    0);
	}
	HAL_CAN_Start(hcan);
	// __HAL_CAN_ENABLE_IT(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	// __HAL_CAN_ENABLE_IT(hcan, CAN_IT_RX_FIFO1_MSG_PENDING);
	HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO1_MSG_PENDING);
}

/**
 * @brief 发送数据帧
 *
 * @param hcan CAN编号
 * @param ID ID
 * @param data 被发送的数据指针
 * @param length 长度
 * @return uint8_t 执行状态
 */
uint8_t can_send_data(CAN_HandleTypeDef* hcan, uint16_t can_ID,
                      uint8_t* data, uint16_t length)
{
	CAN_TxHeaderTypeDef tx_header;
	uint32_t used_mailbox;

	// 检测传参是否正确
	assert_param(hcan != NULL);

	tx_header.StdId = can_ID;
	tx_header.ExtId = 0;
	tx_header.IDE = CAN_ID_STD;
	tx_header.RTR = CAN_RTR_DATA;
	tx_header.DLC = length;

	return (HAL_CAN_AddTxMessage(hcan, &tx_header, data, &used_mailbox));
}

/**
 * @brief HAL库CAN接收FIFO0中断
 *
 * @param hcan CAN编号
 */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* hcan)
{

	if (hcan->Instance == CAN1) {
		HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0,
		                     &can1_manager.rx_buffer.header,
		                     can1_manager.rx_buffer.data);
		can1_manager.call_back_function(&can1_manager.rx_buffer);
	} else if (hcan->Instance == CAN2) {
		HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0,
		                     &can2_manager.rx_buffer.header,
		                     can2_manager.rx_buffer.data);
		can2_manager.call_back_function(&can2_manager.rx_buffer);
    }
}

void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef* hcan)
{

	if (hcan->Instance == CAN1) {
		HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0,
		                     &can1_manager.rx_buffer.header,
		                     can1_manager.rx_buffer.data);
		can1_manager.call_back_function(&can1_manager.rx_buffer);
	} else if (hcan->Instance == CAN2) {
		HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0,
		                     &can2_manager.rx_buffer.header,
		                     can2_manager.rx_buffer.data);
		can2_manager.call_back_function(&can2_manager.rx_buffer);
	}
}
/*========================COPYRIGHT(C) CCUT-DAMOCLES==========================*/
